﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Infragistics.Win.UltraWinGrid;

namespace Billing.Win
{
    [ToolboxItem(true)]
    public partial class ucClientBillingPhones : Billing.WindowsBase.CustomControls.BaseControl
    {
        private const string msgOperSuccess = "ოპერაცია წარმატებით დასრულდა.";
        private const string msgLegislativeMissing = "იურიდიული პირი არ არის შენახული მონაცემთა ბაზაში.";
        private const string msgPhoneNumberMissing = "შეიტანეთ ტელეფონის ნომერი.";
        private const string msgRentalStatusMissing = "აირჩიეთ იჯარის ნიშანი.";
        private const string msgSelectPhoneNumber = "აირჩიეთ ტელეფონის ნომერი.";

        bool inEditMode = false;

        private bool readOnly;
        private bool filterByClientTypeID = false;

        private string phoneNumber;

        [Browsable(false)]
        public string PhoneNumber
        {
            get { return phoneNumber; }
            set { phoneNumber = value; }
        }

        [Browsable(false)]
        public bool FilterByClientTypeID
        {
            get { return filterByClientTypeID; }
            set { filterByClientTypeID = value; }
        }

        public bool ReadOnly
        {
            get { return readOnly; }
            set { SetReadonlyValue(value); }
        }

        private void SetReadonlyValue(bool value)
        {
            this.readOnly = value;
            grbxPhones.Visible = !value;
            TBM.Visible = !value;
        }

        Billing.DataObjects.BillingDataContext context = new Billing.DataObjects.BillingDataContext();

        private Billing.DataObjects.ClientsView client = null;

        public Billing.DataObjects.ClientsView Client
        {
            get { return client; }
        }

        public Billing.DataObjects.AccountsView Account
        {
            get
            {
                return accountsViewBindingSource.Current as Billing.DataObjects.AccountsView;
            }
        }

        public ucClientBillingPhones()
        {
            InitializeComponent();
            InitializeGrid();
            CaptionVisibled = false;
            if (!DesignMode)
            {
                LoadDictionaryData();
                LoadPhonesSource();
            }
            SetInEditMode(false);
        }

        private void InitializeGrid()
        {
            grdPhones.DisplayLayout.ViewStyleBand = Infragistics.Win.UltraWinGrid.ViewStyleBand.OutlookGroupBy;
            grdPhones.DisplayLayout.GroupByBox.Hidden = true;
            grdPhones.DisplayLayout.Bands[0].SortedColumns.Add("AccountType", false, true);
            grdPhones.DisplayLayout.Bands[0].Columns["AccountType"].Hidden = false;
            grdPhones.DisplayLayout.Bands[0].Override.GroupByRowInitialExpansionState = Infragistics.Win.UltraWinGrid.GroupByRowInitialExpansionState.Expanded;
            grdPhones.DisplayLayout.Bands[0].Columns["AccountType"].Header.Caption = "ანგარიშის ტიპი";
            grdPhones.DisplayLayout.Bands[0].Columns["AccountNumber"].Header.Caption = "ნომერი";
            grdPhones.DisplayLayout.Bands[0].Columns["StartDate"].Header.Caption = "ჩართვა";
            grdPhones.DisplayLayout.Bands[0].Columns["EndDate"].Header.Caption = "მოხსნა";
            grdPhones.DisplayLayout.Bands[0].Columns["RentalStatus"].Header.Caption = "იჯარა";
            grdPhones.DisplayLayout.Bands[0].Columns["AccountNumberProviderName"].Header.Caption = "ოპერატორი";

        }

        private void LoadPhonesSource()
        {
            if (DesignMode) return;
            freeAccountNumbersViewBindingSource.DataSource = context.FreeAccountNumbersViews;
        }

        private void LoadDictionaryData()
        {
            if (DesignMode) return;
            rentalStatuseBindingSource.DataSource = context.RentalStatuses;
            valRentalStatus.DataSource = rentalStatuseBindingSource;

        }
        public void Initialize(Billing.DataObjects.ClientsView client)
        {
            Initialize(client, "");
        }
        public void Initialize(Billing.DataObjects.ClientsView client, string phoneNumber)
        {
            SetInEditMode(false);
            if (DesignMode) return;
            this.phoneNumber = phoneNumber;
            this.client = client;
            this.Enabled = client != null && client.ExistsInDB;

            SetFilter(phoneNumber);

            if (client != null)
                accountsViewBindingSource.DataSource = context.AccountsSelect(client.ID, filterByClientTypeID);
        }

        private void SetFilter(string phoneNumber)
        {
            grdPhones.DisplayLayout.Bands[0].ColumnFilters["AccountNumber"].FilterConditions.Clear();
            grdPhones.DisplayLayout.Bands[0].ColumnFilters["AccountNumber"].FilterConditions.Add(new Infragistics.Win.UltraWinGrid.FilterCondition(Infragistics.Win.UltraWinGrid.FilterComparisionOperator.StartsWith, phoneNumber));

        }

        private void ultraCheckEditor1_CheckedChanged(object sender, EventArgs e)
        {
            valEndDate.Enabled = chbEndDate.Checked;
        }

        private void DoAddPhone()
        {
            if (DesignMode) return;

            if (!client.ExistsInDB)
            {
                base.ShowWarning(msgLegislativeMissing);
                return;
            }

            if (string.IsNullOrEmpty(valPhoneNumber.Text))
            {
                base.ShowWarning(msgPhoneNumberMissing);
                return;
            }
            if (valRentalStatus.SelectedItem == null)
            {
                base.ShowWarning(msgRentalStatusMissing);
                return;
            }

            Billing.DataObjects.AccountNumber number = new Billing.DataObjects.AccountNumber();
            number.AccountNumberStatusID = 1;
            number.AccountNumberTypeID = 1;
            number.Number = valPhoneNumber.Text;

            int? accNumberID = null;
            context.AccountNumbersAdd(ref accNumberID, number.Number, number.AccountNumberTypeID, number.AccountNumberStatusID);
            number.ID = accNumberID.Value;


            Billing.DataObjects.AccountsView acc = null;

            if (inEditMode)
                acc = accountsViewBindingSource.Current as Billing.DataObjects.AccountsView;
            else
                acc = new Billing.DataObjects.AccountsView();

            acc.AccountTypeID = 1;
            acc.ClientID = client.ID;
            acc.AccountNumberID = accNumberID.Value;
            acc.AccountNumber = number.Number;
            acc.RentalStatusID = Convert.ToInt16(valRentalStatus.SelectedItem.DataValue);
            if (string.IsNullOrEmpty(acc.RentalStatus))
            {
                acc.RentalStatus = context.GetRentalStatusNameByID(acc.RentalStatusID);
            }
            acc.StartDate = valStartDate.DateTime;
            acc.EndDate = valEndDate.Enabled ? valEndDate.DateTime : (DateTime?)null;
            long? accID = null;

            if (inEditMode)
            {
                context.AccountsUpdate(acc.ID, acc.RentalStatusID, acc.StartDate, acc.EndDate);
                SetInEditMode(false);
            }
            else
            {
                context.AccountsAdd(ref accID, acc.AccountNumberID, acc.ClientID, acc.AccountTypeID, acc.RentalStatusID, acc.StartDate, acc.EndDate);
                accountsViewBindingSource.Add(acc);
            }

            base.ShowInformation(msgOperSuccess);

            CleareFields();

        }

        private void SetInEditMode(bool mode)
        {
            inEditMode = mode;
            valPhoneNumber.Enabled = !mode;
            TBM.Tools["Add"].SharedProps.Visible = !mode;
            TBM.Tools["Edit"].SharedProps.Visible = !mode;
            TBM.Tools["Save"].SharedProps.Visible = mode;
            TBM.Tools["CancelEdit"].SharedProps.Visible = mode;
        }

        private void CleareFields()
        {
            valPhoneNumber.Text = string.Empty;
            valPhoneNumber.Select(0, 1);
            chbEndDate.Checked = false;
            valEndDate.Value = null;
        }

        private void TBM_ToolClick(object sender, Infragistics.Win.UltraWinToolbars.ToolClickEventArgs e)
        {
            try
            {
                switch (e.Tool.Key)
                {
                    case "Add":    // ButtonTool
                        DoAddPhone();
                        break;
                    case "Save":    // ButtonTool
                        DoAddPhone();
                        break;
                    case "Edit":    // ButtonTool
                        DoEditPhone();
                        break;
                    case "CancelEdit":
                        SetInEditMode(false);
                        CleareFields();
                        break;
                }
            }
            catch (Exception x)
            {
                base.ShowError(x);
            }
        }

        private void DoEditPhone()
        {
            OnAccountEdit();
        }

        public event EventHandler CurrentChanged;
        public new event EventHandler DoubleClick;

        private void accountsViewBindingSource_CurrentChanged(object sender, EventArgs e)
        {
            if (inEditMode)
                OnAccountEdit();

            if (CurrentChanged != null)
                CurrentChanged(this, e);

        }

        private void OnDoubleClick()
        {
            OnAccountEdit();
            if (this.DoubleClick != null)
                this.DoubleClick(this, EventArgs.Empty);
        }

        protected virtual void OnAccountEdit()
        {
            Billing.DataObjects.AccountsView activeAcc = accountsViewBindingSource.Current as Billing.DataObjects.AccountsView;
            if (activeAcc == null)
            {
                if (inEditMode)
                {
                    CleareFields();
                    SetInEditMode(false);
                }
                return;
            }
            SetInEditMode(true);

            valPhoneNumber.Text = activeAcc.AccountNumber;
            valRentalStatus.Value = activeAcc.RentalStatusID;
            valStartDate.DateTime = activeAcc.StartDate;
            chbEndDate.Checked = activeAcc.EndDate != null;
            if (chbEndDate.Checked)
                valEndDate.DateTime = activeAcc.EndDate.Value;
        }

        private void grdPhones_Click(object sender, EventArgs e)
        {
            if (accountsViewBindingSource.Count == 1)
                if (CurrentChanged != null)
                    CurrentChanged(this, e);
        }


        #region Grid Row DoubleClick Event
        UltraGridRow PupUpRow;
        System.Collections.BitArray GridEvents = new System.Collections.BitArray(2, false);

        private enum GridElements
        {
            Row,
            GroupBox
        }

        private void Grid_MouseEnterElement(object sender, Infragistics.Win.UIElementEventArgs e)
        {
            try
            {
                if (e.Element is CellUIElement || e.Element is RowSelectorUIElement)
                {
                    this.SetGridEventValue(GridElements.Row, true);
                    if (e.Element is CellUIElement)
                        PupUpRow = ((CellUIElement)e.Element).Row;
                    else if (e.Element is RowSelectorUIElement)
                        PupUpRow = ((RowSelectorUIElement)e.Element).Row;
                }
                else if (e.Element is GroupByBoxUIElement)
                    this.SetGridEventValue(GridElements.GroupBox, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace);
            }
        }

        private void Grid_MouseLeaveElement(object sender, Infragistics.Win.UIElementEventArgs e)
        {
            try
            {
                if (e.Element is CellUIElement || e.Element is RowSelectorUIElement)
                {
                    this.SetGridEventValue(GridElements.Row, false);
                    PupUpRow = null;
                }
                else if (e.Element is GroupByBoxUIElement)
                    this.SetGridEventValue(GridElements.GroupBox, false);
            }
            catch (Exception ex)
            { MessageBox.Show(ex.StackTrace); }

        }

        private void Grid_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            try
            {
                switch (e.Button)
                {
                    case MouseButtons.Left:
                        if (e.Clicks == 2 && this.GetGridEventValue(GridElements.Row))
                        {
                            OnDoubleClick();
                        }
                        else if (e.Clicks == 2 && this.GetGridEventValue(GridElements.GroupBox))
                            this.grdPhones.ShowColumnChooser(true);
                        break;
                    case MouseButtons.Middle:
                        break;
                    case MouseButtons.None:
                        break;
                    case MouseButtons.Right:
                        if (e.Clicks == 1 && this.GetGridEventValue(GridElements.Row))
                            if (PupUpRow != null)
                            {
                                PupUpRow.Activate();
                                PupUpRow.Selected = true;
                            }
                        break;
                    case MouseButtons.XButton1:
                        break;
                    case MouseButtons.XButton2:
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }

        private void SetGridEventValue(GridElements GridEvent, bool Value)
        { this.GridEvents[(int)GridEvent] = Value; }

        private bool GetGridEventValue(GridElements Gridevent)
        { return this.GridEvents[(int)Gridevent]; }

        #endregion
    }
}
